package com.gitee.wsl.mathematics.geometry.d2.line.ext

import com.gitee.wsl.mathematics.coordinate.d2.Coordinate2
import com.gitee.wsl.mathematics.geometry.d2.line.LineShape2d
import com.gitee.wsl.mathematics.number.compareTo
import com.gitee.wsl.mathematics.vector.ext.dot
import com.gitee.wsl.mathematics.vector.ext.minus

/**
 * Computes the closest point on the given edge to the specified point.
 *
 * @param point
 * The point to which we search the closest point on the edge
 * @return The closest point on the given edge to the specified point
 */
fun<T:Number,V: Coordinate2<T, V>> LineShape2d<T, V>.computeClosestPoint(point: Coordinate2<T, *>): V {

    val ab  = b - a
    var t = (point-a).dot(ab) / ab.dot(ab)

    if (t < zero) {
        t = zero
    } else if (t > one) {
        t = one
    }

    return a + (ab * t)
}